/*
 * Copyright (c) 2023-2023 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.oss.api.config;

import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.elsfs.cloud.oss.api.FileTemplate;
import org.elsfs.cloud.oss.api.LocalFileTemplate;
import org.elsfs.cloud.oss.api.OssTemplate;
import org.elsfs.cloud.oss.api.endpoint.OssController;
import org.elsfs.cloud.oss.api.properties.FileProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * oss 配置
 *
 * @author zeng
 */
@EnableConfigurationProperties(FileProperties.class)
@Configuration
@RequiredArgsConstructor
public class OssConfig {

  @RequiredArgsConstructor
  @ConditionalOnProperty(name = "file.local.enable", havingValue = "true", matchIfMissing = true)
  static class LocalFileAutoConfiguration {
    private final FileProperties properties;

    /**
     * 本地模式
     *
     * @return FileTemplate
     */
    @Bean
    public FileTemplate localFileTemplate() {
      return new LocalFileTemplate(properties);
    }
  }

  /** 配置oss信息 */
  @AllArgsConstructor
  @ConditionalOnProperty(name = "file.oss.enable", havingValue = "true")
  public static class OssAutoConfiguration {

    /** FileProperties类的私有final成员变量。 该变量用于存储文件属性相关信息，是一个不可变的对象。 */
    private final FileProperties properties;

    /**
     * 创建并返回一个OssTemplate实例。
     * 该方法使用条件注解@ConditionalOnMissingBean，只有在当前应用上下文中不存在OssTemplate类型的Bean时，才会执行并创建一个新的OssTemplate实例。
     * 使用@Primary注解表明，如果存在多个候选Bean时，该实例应作为首选Bean被注入到其他依赖它的地方。
     *
     * @return 返回配置好的OssTemplate实例，用于与OSS（Amazon S3或类似服务）进行交互。
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean(OssTemplate.class)
    public FileTemplate ossTemplate() {
      return new OssTemplate(properties); // 基于配置的properties创建OssTemplate实例
    }
  }

  /**
   * 根据属性文件中"file.oss.enableEndpoint"的值决定是否创建并返回一个OssEndpoint实例。
   * 该方法只有在"file.oss.enableEndpoint"的值为"true"时才会被调用。
   *
   * @param template OssTemplate，OSS操作的模板，用于在OssEndpoint中进行具体的OSS操作。
   * @return OssController.OssEndpoint，OSS的端点实体，提供访问OSS的接口。
   */
  @Bean
  @ConditionalOnProperty(name = "file.oss.enableEndpoint", havingValue = "true")
  public OssController.OssEndpoint ossEndpoint(OssTemplate template) {
    return new OssController.OssEndpoint(template);
  }
}
